/** LoginPanel */
package client.ui.panel;

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Logger;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import org.json.JSONArray;
import org.json.JSONObject;

import client.ClientManager;
import client.EventBus;
import client.events.ViewHome;
import client.io.ClientIO;
import client.service.UserService;
import domain.action.Action;
import domain.permissions.Permission;
import domain.session.Request;
import domain.session.Response;
import domain.user.SystemUser;

/**
 * Creates a login page containing a username and password field
 * 
 * @author jessienewman
 * @version $Revision: 1.0 $
 */
public class LoginPanel extends JPanel {
	/**
	 * Field LOGGER.
	 */
	private static final Logger LOGGER = Logger.getLogger(LoginPanel.class
			.getName());

	/**
	 * Field textField.
	 */
	private JTextField textField;

	/**
	 * Field passField.
	 */
	private JPasswordField passField;

	/**
	 * Field button.
	 */
	private JButton button;

	/**
	 * Field error.
	 */
	private JLabel error;

	/**
	 * Field title.
	 */
	private JLabel title;

	/**
	 * Field badLogin.
	 */
	private int badLogin; // $codepro.audit.disable variableShouldBeFinal

	/**
	 * Field uipanel.
	 */
	private JPanel uipanel;

	/**
	 * Field layout.
	 */
	private CardLayout layout;

	private JPanel panel;
	
	private URL scope = getClass().getResource("Stethoscope_medium.jpg");
	private ImageIcon bg=new ImageIcon(scope);
	private Image background=bg.getImage();
	
	/**
	 * Creates a login page containing a username and password field *
	 * 
	 * @param layout
	 *            CardLayout
	 */
	public LoginPanel(CardLayout layout) {
		panel=new JPanel();
		this.layout = layout;
		uipanel = this;
		this.setBackground(Color.WHITE);

		// initialize variables
		badLogin = 0;
		textField = new JTextField(20); // $codepro.audit.disable
										// numericLiterals
		textField.addActionListener(new LoginListener());
		passField = new JPasswordField(10); // $codepro.audit.disable
											// numericLiterals
		passField.addActionListener(new LoginListener());
		error = new JLabel(" ");
		error.setForeground(Color.RED);
		error.setFont(error.getFont().deriveFont(
				error.getFont().getStyle() ^ Font.BOLD));
		button = new JButton("Login");
		button.addActionListener(new LoginListener());
		URL titleUrl = getClass().getResource("title.jpg");
		ImageIcon titleImage = new ImageIcon(titleUrl);
		title = new JLabel(titleImage);
		// passField.setActionCommand(OK);
		// passField.addActionListener(this);

		setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();

		// add panel components
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 2; // $codepro.audit.disable numericLiterals
		this.add(title, c);

		c.gridy++;
		this.add(error, c);

		c.gridy++;
		c.gridwidth = 1;
		this.add(new JLabel("Username:"), c);

		c.gridx++;
		c.fill = GridBagConstraints.HORIZONTAL;
		this.add(textField, c);

		c.gridx = 0;
		c.gridy++;
		c.fill = GridBagConstraints.NONE;
		this.add(new JLabel("Password:"), c);

		c.gridx++;
		c.fill = GridBagConstraints.HORIZONTAL;
		this.add(passField, c);

		c.gridx = 0;
		c.gridy++;
		this.add(button, c);
	}

	/**
	 * returns the super's toString
	 * 
	 * @return String super's toString
	 */
	public String toString() {
		return super.toString();
	}
	
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(background,0,0, null);
	}

	/**
	 * Listens for login attempt
	 * 
	 * @author jessienewman
	 */
	private class LoginListener implements ActionListener { // $codepro.audit.disable
															// com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString
		/**
		 * Allows user to login with correct credentials. Locks user out after 3
		 * incorrect attemtps
		 * 
		 * @param event
		 *            ActionEvent
		 * 
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
		 */
		public void actionPerformed(ActionEvent event) {
			String username = textField.getText();
			String password = passField.getText();

			LOGGER.info("Attempting to login");
			SystemUser user = new SystemUser();
			user.setUsername(username);
			user.setPassword(password);

			JSONObject loginObject = new JSONObject();
			loginObject.put("username", user.getUsername());

			/**
			 * Encrypts the given password using SHA-256.
			 */			
			try { 
				byte[] passByte = user.getPassword().getBytes("ASCII");
				MessageDigest digest = MessageDigest.getInstance("SHA-256");
				digest.update(passByte);
				loginObject.put("password", new String(digest.digest(), "ASCII")); 
			} catch (UnsupportedEncodingException ue) {
				ue.printStackTrace(); 
			} catch (NoSuchAlgorithmException ne) {
				ne.printStackTrace();
			}

			ClientIO.sendRequest(new Request(Action.LOGIN, loginObject));

			Response response = ClientIO.getResponse();
			JSONObject loginJson = response.getResponse();

			String msg = loginJson.getString("msg");

			if (!response.isSuccessful()) {
				error.setText(msg);
				LOGGER.info(msg);
				LOGGER.info(loginJson.toString());
				if (loginJson.getBoolean("lock")) { // $codepro.audit.disable
													// nullPointerDereference
					UserService.getUser(UserService.getUserId(username)).setActive(false);
				}
			} else {
				if ((UserService.thisIsValidUsername(username) && !UserService.getUser(
						UserService.getUserId(username)).isActive())) {
					error.setText("You have been locked out. Contact an administrator.");
					return;
				}
				try {
					Integer userId = loginJson.getInt("userId");
					ClientManager.SESSION.setUserId(userId);
				} catch (NumberFormatException nfe) {
					LOGGER.warning("Number Format Exception: " + nfe);
				}

				JSONArray permissionArray = (JSONArray) loginJson
						.get("permissions");

				for (int i = 0; i < permissionArray.length(); i++) {
					ClientManager.SESSION.addPermission(Permission
							.getPermission(permissionArray.getString(i)));
				}
				// for (layout)

				EventBus.BUS.fireEvent(new ViewHome(user));
				//setOpaque(false);
				//show();
				//next(this);
			}
		}
	}

}
